/******************************************************************************
 * @file     system_NANO1xx.c
 * @author   NuMicro MCU Software Team
 * @version  V1.01
 * @date     26. November 2010
 * @brief    CMSIS ARM Cortex-M0 Device Peripheral Access Layer Source File
 *
 * @note
 * Copyright (C) 2010 Nuvoton Technology Corp. All rights reserved.
 *
 * @par
 * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
 * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 ******************************************************************************/


#include <stdint.h>
#include "NANO1xx.h"

/*----------------------------------------------------------------------------
  Clock Variable definitions
 *----------------------------------------------------------------------------*/
uint32_t SystemCoreClock  = __HSI;   /*!< System Clock Frequency (Core Clock) */

uint32_t gau32ClkSrcTbl[] = {__XTAL, __RTC_XTAL, __HSI, __IRC10K, __IRC12M};

/*----------------------------------------------------------------------------
  Clock functions
 *----------------------------------------------------------------------------*/
void SystemCoreClockUpdate (void)            /* Get Core Clock Frequency      */
{
  /* Determine clock frequency according to clock register values             */
    uint32_t u32CoreFreq, u32ClkSrc;
    uint32_t u32NO, u32NR, u32hclk;
 
    u32ClkSrc = CLK->CLKSEL0;
    if(u32ClkSrc > sizeof(gau32ClkSrcTbl)/sizeof(gau32ClkSrcTbl[0]))
        u32ClkSrc = sizeof(gau32ClkSrcTbl)/sizeof(gau32ClkSrcTbl[0]) - 1; 
    
    if(u32ClkSrc != 2)
    {
        /* Use the clock sources directly */
        u32CoreFreq = gau32ClkSrcTbl[u32ClkSrc];
    }
    else
    {
        /* Use PLL */
        u32NO = ((CLK->PLLCTL_BITS.OUT_DV)? 2: 1);
		if (CLK->PLLCTL_BITS.IN_DV == 0)
			u32NR = 2;
		else if (CLK->PLLCTL_BITS.IN_DV == 1)
			u32NR = 4;
		else if (CLK->PLLCTL_BITS.IN_DV == 2)
			u32NR = 8;
		else
			u32NR = 16;
        u32CoreFreq = ((CLK->PLLCTL_BITS.PLL_SRC)?__IRC12M:__XTAL) * (CLK->PLLCTL_BITS.FB_DV+32) / u32NR / u32NO;
    }

    u32hclk = CLK->CLKDIV0_BITS.HCLK_N;
    SystemCoreClock = (u32CoreFreq/(u32hclk + 1));
    
}

/**
 * Initialize the system
 *
 * @param  none
 * @return none
 *
 * @brief  Setup the microcontroller system.
 *         Initialize the System and update the SystemFrequency variable.
 */
void SystemInit (void)
{
#ifdef CMNTEST
  GPIO0->DATA[0].WORD = 0;
  GPIO0->IE = 0;
  GPIO0->DIR = 0xff83;
  
  GPIO1->DATA[0].WORD = 0;
  GPIO1->IE = 0;
  GPIO1->DIR = 0;
  
  GPIO2->DATA[0].WORD = 0;
  GPIO2->IE = 0;
  GPIO2->DIR = 0;
#endif  
}

